import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.swing.JFrame;

import torque.generated.*;

import javax.swing.JPanel;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Panel;

import javax.swing.JLabel;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JTextPane;

import org.apache.torque.TorqueException;

import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.math.*;


public class VueJeu extends Vue{
	private JButton btnEquiper;
	private JButton btnUtiliser;
	private JButton btnIntercepter;
	private JButton btnAttaquer;
	private JButton btnDeplacer;
	private JLabel lblJoueur;
	private JButton btnMenu;
	private JPanel panelGrille;
	
	// Variables des éléments de la grille 
	private BoutonGrille btnGrilleSelectionne;
	private Partie partieCourante;
	private Vector<Positionobjet> objetsDansPartie = new Vector<Positionobjet>();
	private Vector<Positionvaisseau> vaisseauxDansPartie = new Vector<Positionvaisseau>();
	private Inventaire inventaireVaisseau1 = new Inventaire();
	private Inventaire inventaireVaisseau2 = new Inventaire();
	// création d'un vecteur de boutons pour pouvoir changer le texte des boutons après création
	final Vector<BoutonGrille> vBoutons = new Vector<BoutonGrille>();
	
	public VueJeu(Controleur controleur, Partie p1, Echiquier e1, 
				  Positionvaisseau positionvaisseau, Positionvaisseau positionvaisseau2,
				  Inventaire inventaireVaisseau1, Inventaire inventaireVaisseau2,
				  List<Objet> objets) throws Exception{
		super(controleur);
		setPartie(p1);
		Integer nbLignes = e1.getY();
		Integer nbColones = e1.getX();
		setTitle("StarAttack");
		// Affichage de la fenêtre non redimensionable
		setLocationRelativeTo(this.getParent());
		setVisible(true);
		setResizable(false);
		// Affectation de la dimension minimale pour la fenêtre
		Dimension dimMini = new Dimension();
		dimMini.height = 465;
		dimMini.width = 590;
		setMinimumSize(dimMini);
		// Ajout du layout a la fenêtre (position absolue)
		getContentPane().setLayout(null);
		
		btnDeplacer = new JButton("Déplacer");
		btnDeplacer.setBounds(444, 82, 120, 25);
		btnDeplacer.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				Positionvaisseau vaisseauCourant = vaisseauxDansPartie.get(0);
				if(partieCourante.getIdjoueur()==0){
					vaisseauCourant = vaisseauxDansPartie.get(0);
				}
				else{
					vaisseauCourant = vaisseauxDansPartie.get(1);
				}
				IO.Message("Vaisseau courant : " + vaisseauCourant.getX() + " " + vaisseauCourant.getY());
					if(estDeplacable(vaisseauCourant, btnGrilleSelectionne)){
						vaisseauCourant.setPtaction(vaisseauCourant.getPtaction()-1);
						for (int i=0; i<vBoutons.size(); i++){
							if(vBoutons.get(i).getPosX()==vaisseauCourant.getX() && 
							   vBoutons.get(i).getPosY()==vaisseauCourant.getY()){
								vBoutons.get(i).getBouton().setText("");
							}
						}
						IO.Message("BoutonSelectionne : "+ btnGrilleSelectionne.getPosX() + " " + btnGrilleSelectionne.getPosY());
						Integer posX = btnGrilleSelectionne.getPosX(); Integer posY = btnGrilleSelectionne.getPosY();
						IO.Message("Positions : "+posX+ " "+ posY);
						IO.Message(vaisseauCourant.getX()+ " " +  vaisseauCourant.getY());
						vaisseauCourant.setX(posX);
						vaisseauCourant.setX(posY);
						IO.Message("Vaisseau courant :" + vaisseauCourant.getX() + " " + vaisseauCourant.getY());
						VueJeu.this.actualiserAffichageGrille(vaisseauxDansPartie, objetsDansPartie);
					}else{
						IO.Message("impossible de déplacer le vaisseau sur cette case");
					}
			}
		});
		getContentPane().add(btnDeplacer);
		
		btnAttaquer = new JButton("Attaquer");
		btnAttaquer.setBounds(444, 107, 120, 25);
		btnAttaquer.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				
			}
		});
		getContentPane().add(btnAttaquer);
		
		btnIntercepter = new JButton("intercepter");
		btnIntercepter.setBounds(444, 132, 120, 25);
		btnIntercepter.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				
			}
		});
		getContentPane().add(btnIntercepter);
		
		btnUtiliser = new JButton("Utiliser");
		btnUtiliser.setBounds(444, 157, 120, 25);
		btnUtiliser.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				
			}
		});
		getContentPane().add(btnUtiliser);
		
		btnEquiper = new JButton("Equiper");
		btnEquiper.setBounds(444, 182, 120, 25);
		btnEquiper.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				
			}
		});
		getContentPane().add(btnEquiper);
		
		lblJoueur = new JLabel("Joueur 1");
		lblJoueur.setBounds(470, 55, 61, 15);
		getContentPane().add(lblJoueur);
		
		btnMenu = new JButton("Menu");
		btnMenu.setBounds(444, 246, 117, 25);
		btnMenu.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				getControleur().lancerVueMenuInter(VueJeu.this);
			}
		});
		getContentPane().add(btnMenu);
		
		panelGrille = new JPanel();
		panelGrille.setBounds(10, 10, 420, 420);
		getContentPane().add(panelGrille);
	
		this.generationGrille(nbLignes, nbColones, positionvaisseau, positionvaisseau2, objets);
	}


	private boolean partieFinie() {
		Iterator vaisseaux = vaisseauxDansPartie.iterator();
		while(vaisseaux.hasNext()){
			// TODO tester si l'énergie du joueur est ==0
			if(((Vaisseau)vaisseaux.next()).getPtenergie()==0){
				return true;
			}
			else
				return false;
		}
		return true;

	}
	
	private void IntercepterObjet(Positionvaisseau pv1, Positionobjet obj1){
		objetsDansPartie.remove(obj1);
		//getControleur().ajouterObjetVaisseau(pv1, obj1);
	}


	private void setPartie(Partie p1) {
		this.partieCourante=p1;		
	}


	public void generationGrille(Integer nbLignes, Integer nbColones, Positionvaisseau v1, Positionvaisseau v2, List<Objet> objets) throws TorqueException{
		GridLayout grilleJeu = new GridLayout(nbLignes, nbColones);
		panelGrille.setLayout(grilleJeu);
		// définition de la valeur des marges intérieures du bouton 
		// pour pouvoir afficher ce qu'il y a dedans sans qu'il remplace par "..."
		Insets margesInter = new Insets(0, 0, 0, 0);
		margesInter.bottom=1;
		margesInter.left=1;
		margesInter.right=1;
		margesInter.top=1;
		// fin définitions marges
		for (int i = 0; i < nbLignes*nbColones; i++) {
			// création d'un bouton et ajout dans le vecteur de boutons
			Integer positionX;
			Integer positionY;
			positionX = (i%nbColones)+1;
			positionY = (i-(i%nbLignes))/nbLignes+1;
 			vBoutons.add(new BoutonGrille(positionX, positionY));
			panelGrille.add(vBoutons.lastElement().getBouton());
			// affectation marge au bouton 
			vBoutons.lastElement().getBouton().setMargin(margesInter);
			// passer la couleur de fond du bouton a blanc
			vBoutons.lastElement().getBouton().setBackground(Color.WHITE);
			// ajout de la procédure déclanchee lors d'un clic
			vBoutons.lastElement().getBouton().addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					for (Integer i=0;i<vBoutons.size();i++){
						JButton boutonVecteur = vBoutons.get(i).getBouton();
						boutonVecteur.setBackground(Color.WHITE);
					}
					JButton boutonSelectionne = (JButton)e.getSource();
					boutonSelectionne.setBackground(Color.LIGHT_GRAY);
					Iterator itrVBoutons = vBoutons.iterator();
					while (itrVBoutons.hasNext()){
						BoutonGrille bGrilleVecteur = (BoutonGrille) itrVBoutons.next();
						if (boutonSelectionne.equals(bGrilleVecteur.getBouton())){
							IO.Message("Vous avez sélectionné sur la case en : x=" + bGrilleVecteur.getPosX() + " y=" + bGrilleVecteur.getPosY());
							btnGrilleSelectionne = bGrilleVecteur;
							
						}	
					}
				}
			});
		}
		
		if (objets==null){
			Positionvaisseau pv1 = new Positionvaisseau(), pv2= new Positionvaisseau();
			pv1.setX((int)nbColones/2);
			pv1.setY(1);
			pv1.setNomvaisseau(v1.getNomvaisseau());
			pv1.setNompartie(partieCourante.getNomp());
			pv2.setX((int)nbColones/2);
			pv2.setY(nbLignes);
			pv2.setNomvaisseau(v2.getNomvaisseau());
			pv2.setNompartie(partieCourante.getNomp());
			vaisseauxDansPartie.add(pv1);
			vaisseauxDansPartie.add(pv2);
			
			for (int i = 0; i < nbLignes*nbColones/3; i++){
				Integer positionX = (int) (Math.random()*nbColones);
				Integer positionY = (int) (Math.random()*nbLignes);
				if (!vaisseauProximiteObjet(positionX, positionY)){
				Positionobjet obj = new Positionobjet();
				obj.setX(positionX);
				obj.setY(positionY);
				obj.setNomobjet(getControleur().getNomAleatoireObjet());
				obj.setNompartie(partieCourante.getNomp());
				objetsDansPartie.add(obj);
				}
			}
		}
		else{
			vaisseauxDansPartie.add(v1);
			vaisseauxDansPartie.add(v2);
			Iterator itr = objets.iterator();
			while(itr.hasNext()){
				objetsDansPartie.add((Positionobjet) itr.next());
			}
		}	
		this.actualiserAffichageGrille(vaisseauxDansPartie, objetsDansPartie);
	}
	
	private boolean vaisseauProximiteObjet(Integer positionX, Integer positionY) {
		Iterator itr = vaisseauxDansPartie.iterator();
		while (itr.hasNext()){
			Positionvaisseau pvaisseau = (Positionvaisseau) itr.next();
			if (positionX==pvaisseau.getX() && positionY==pvaisseau.getY() || 
				positionX>pvaisseau.getX()-2 && positionX<pvaisseau.getX()+2 || 
				positionY>pvaisseau.getY()-2 && positionY<pvaisseau.getY()+2 ){
				return true;
				}
		}
		return false;
	}
	
	private boolean objetSurCase(Integer positionX, Integer positionY){
		Iterator itr = objetsDansPartie.iterator();
		while (itr.hasNext()){
			Positionobjet pobjet = (Positionobjet) itr.next();
			if (positionX==pobjet.getX() && positionY==pobjet.getY()){
				return true;
				}
		}
		return false;
	}


	private void actualiserAffichageGrille(Vector<Positionvaisseau> vaisseauxDansPartie,
										   Vector<Positionobjet> objetsDansPartie) {
		//TODO afficher correctement la grille
		// positionnement des symboles des vaisseaux
			Positionvaisseau pv1 = vaisseauxDansPartie.get(0);
			Positionvaisseau pv2 = vaisseauxDansPartie.get(1);
			JButton caseVaisseau1 = getBoutonPosition(pv1.getX(),pv1.getY());
			JButton caseVaisseau2 = getBoutonPosition(pv2.getX(),pv2.getY());
			caseVaisseau1.setText("-€-");
			caseVaisseau2.setText("-¶-");
		// positionnement des symboles des objets
			Iterator itr = objetsDansPartie.iterator();
			while(itr.hasNext()){
				Positionobjet pobj = (Positionobjet) itr.next();
				JButton jbt = getBoutonPosition(pobj.getX()+1,pobj.getY()+1);
				jbt.setText("-o-");
			}
	}
	
	private JButton getBoutonPosition(Integer x, Integer y){
		Iterator itr = vBoutons.iterator();
		while (itr.hasNext()){
			BoutonGrille btg = (BoutonGrille) itr.next();
			if (btg.getPosX()==x && btg.getPosY()==y){
				return btg.getBouton();
			}
		}
		return null;
	}

	public boolean estDeplacable(Positionvaisseau pv, BoutonGrille bg){
	// test si le vaisseau en position : pv est déplaçable en case : bg  
	// -1 si déplacement impossible
		Integer difX =pv.getX()-bg.getPosX();
		Integer difY =pv.getY()-bg.getPosY();
			if(Abs(difX)==1 || Abs(difY)==1){
				return true;
			}
			else{
				return false;
			}
	}


	private Integer Abs(Integer a) {
		if(a<0){
			return -a;
		}
		return a;
	}


	public Vector<Positionvaisseau> getPositionsVaisseaux() {
		return this.vaisseauxDansPartie;
	}

	public Vector<Positionobjet> getPositionsObjets() {
		return this.objetsDansPartie;
	}
	
	public Partie getPartieCourante(){
		return this.partieCourante;
	}
}
	
